﻿using MediatorSample.Classes;
using MuddyBoots.Greenlight.QC.Common.Patterns.Behaviour.Mediator;
using System.ComponentModel;
using System.Windows.Input;

namespace MediatorSample
{
    /// <summary>
    /// This is the view model for the TextDisplayControl (view)
    /// </summary>
    public class TextDisplayViewModel : MediatorListener, INotifyPropertyChanged
    {
        #region WPF MVVM stuff

        /// <summary>
        /// The current display text
        /// </summary>
        private string currentDisplayText;

        /// <summary>
        /// The unregister command
        /// </summary>
        private ICommand unregisterCommand;

        /// <summary>
        /// The register command
        /// </summary>
        private ICommand registerCommand;

        /// <summary>
        /// The registration parameters
        /// </summary>
        private RegisterParameter registerParameters;

        /// <summary>
        /// [True] id not regsisterd, else [False]
        /// </summary>
        private bool canRegister = true;

        /// <summary>
        /// Initializes a new instance of the <see cref="TextDisplayViewModel"/> class.
        /// </summary>
        public TextDisplayViewModel()
        {
            this.registerParameters = new RegisterParameter("TextChanged", this.InstanceId, this.OnTextChanged);
            this.RegisterCommand = new RelayCommand(Register, parameter => this.canRegister);
            this.UnregisterCommand = new RelayCommand(Unregister, parameter => !this.canRegister);
        }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Gets or sets the current display text.
        /// </summary>
        /// <value>
        /// The current display text.
        /// </value>
        public string CurrentDisplayText
        {
            get
            {
                return this.currentDisplayText;
            }

            set
            {
                this.currentDisplayText = value;
                this.PropertyChanged(this, new PropertyChangedEventArgs("CurrentDisplayText"));
            }
        }

        /// <summary>
        /// Gets the register parameters.
        /// </summary>
        /// <value>
        /// The register parameters.
        /// </value>
        public RegisterParameter RegisterParameters
        {
            get
            {
                return this.registerParameters;
            }

        }

        /// <summary>
        /// Gets or sets the register command.
        /// </summary>
        /// <value>
        /// The register command.
        /// </value>
        public ICommand RegisterCommand
        {
            get
            {
                return registerCommand;
            }

            set
            {
                registerCommand = value;
            }
        }

        /// <summary>
        /// Gets or sets the unregister command.
        /// </summary>
        /// <value>
        /// The unregister command.
        /// </value>
        public ICommand UnregisterCommand
        {
            get
            {
                return this.unregisterCommand;
            }

            set
            {
                this.unregisterCommand = value;
            }
        }

        /// <summary>
        /// Called when [text changed].
        /// </summary>
        /// <param name="obj">The object.</param>
        private void OnTextChanged(object obj)
        {
            var argument = MediatorHelper<string>.GetArgument(obj);
            this.CurrentDisplayText = argument;
        }

        #endregion

        /// <summary>
        /// Called when the register button is clicked
        /// This tells the mediator to let this instance know when a specific message is broadcast
        /// </summary>
        /// <param name="obj">The object.</param>
        private void Register(object obj)
        {
            var parameter = obj as RegisterParameter;
            if (parameter != null)
            {
                Mediator.Register(parameter.Token, parameter.InstanceId, parameter.Action);
            }

            this.canRegister = false;
        }

        /// <summary>
        /// Unregisters the current instance.
        /// If a class is to be disposed of then mediator regsistrations must be removed
        /// to allow the garbage collector to collect the object.
        /// </summary>
        /// <param name="obj">The object.</param>
        private void Unregister(object obj)
        {
            Mediator.UnregisterAll(this.InstanceId);
            this.canRegister = true;
        }
    }
}
